package com.itheima.service.serviceimpl;

import com.itheima.dao.ReportDao;
import com.itheima.pojo.*;
import com.itheima.service.ReportService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class ReportServiceImpl implements ReportService {

    @Autowired
    private ReportDao reportDao;

    @Transactional
    public MemberReportVo getMemberReport() {
        List<LocalDate> list = new ArrayList<>();
        List<String> months = new ArrayList<>();
        List<Integer> memberCounts = new ArrayList<>();
        LocalDate now = LocalDate.now();
        //获取今天之前的12个月每月的最后一天
        for (int i = 12; i > 0; i--) {
            LocalDate lastDayOfMonth = now.minusMonths(i).withDayOfMonth(now.minusMonths(i).lengthOfMonth());
            list.add(lastDayOfMonth);
        }
        log.info("list:{}", list);
        for (LocalDate localDate : list) {
            //把日期格式变为2022.1.1
            String format = localDate.toString().replace("-", ".");
            months.add(format);
            Integer memberCount = reportDao.selectMemberCount(localDate);
            memberCounts.add(memberCount);
        }



        return MemberReportVo.builder()
                .months(months)
                .memberCount(memberCounts)
                .build();
    }

    @Transactional
    public SetmealReportVO getSetmealReport() {
        List<SetmealVO> setmealVOList = new ArrayList<>();
        //统计所有的被预约的套餐名称
        List<String> setmealNames = reportDao.selectSetmealNames();

        //统计套餐预约数量
        for (String setmealName : setmealNames) {
            SetmealVO setmealVO = SetmealVO.builder()
                    .name(setmealName)
                    .value(reportDao.selectSetmealCountByName(setmealName))
                    .build();
            setmealVOList.add(setmealVO);
        }

        return SetmealReportVO.builder().setmealCount(setmealVOList).setmealNames(setmealNames).build();
    }

    @Transactional
    public BusinessReportDataVO getBusinessReportData() {
        //获取今天日期
        LocalDate now = LocalDate.now();

        //获取本周第一天
        LocalDate firstDayOfWeek = now.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));


        //获取本月第一天
        LocalDate firstDayOfMonth = now.withDayOfMonth(1);


        LocalDate lastDayOfMonth = now.with(TemporalAdjusters.lastDayOfMonth());


        List<HotSetmealVO> hotSetmealVO = new ArrayList<>();
        //统计全部的套餐预约数量
        int orderCount = reportDao.selectSetmealReport();

        //统计所有的被预约的套餐名称
        List<String> setmealNames = reportDao.selectSetmealNamesLimit4();

        for (String setmealName : setmealNames) {
            //根据套餐名称查询套餐预约数量
            int setmealCount = reportDao.selectSetmealCountByName(setmealName);
            double proportion = (double) setmealCount / orderCount;
            String formattedProportion = String.format("%.4f", proportion);

            HotSetmealVO hotSetmealVO1 = HotSetmealVO.builder()
                    .name(setmealName)
                    .setmeal_count(setmealCount)
                    .proportion(formattedProportion)
                    .build();
            hotSetmealVO.add(hotSetmealVO1);
        }
        return BusinessReportDataVO.builder().reportDate(now)
                .todayNewMember(reportDao.selectMemberCountReport(now))
                .totalMember(reportDao.selectMemberCountReport(null))
                .thisWeekNewMember(reportDao.selectMemberCountReport(firstDayOfWeek))
                .thisMonthNewMember(reportDao.selectMemberCountReport(firstDayOfMonth))
                .todayOrderNumber(reportDao.selectOrderReport(now))
                .thisWeekOrderNumber(reportDao.selectOrderReport(firstDayOfWeek))
                .thisMonthOrderNumber(reportDao.selectOrderReport(firstDayOfMonth))
                .todayVisitsNumber(reportDao.selectVisitsReport(now))
                .thisWeekVisitsNumber(reportDao.selectVisitsReport(firstDayOfWeek))
                .thisMonthVisitsNumber(reportDao.selectVisitsReport(firstDayOfMonth))
                .hotSetmeal(hotSetmealVO)
                .build();
    }

    //导出报表
    @Override
    public void exportBusinessReport(HttpServletResponse response) {
        // 设置HTTP响应头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=business_report.xlsx");

        //获取数据
        BusinessReportDataVO businessReportDataVO = getBusinessReportData();
        List<HotSetmealVO> hotSetmeal = businessReportDataVO.getHotSetmeal();

        //通过POI将数据写入Excel文件
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx");
        //基于模板文件生成Excel对象
        try {
            XSSFWorkbook excel = new XSSFWorkbook(is);
            XSSFSheet sheet = excel.getSheet("Sheet1");
            //填充日期
            sheet.getRow(2).getCell(5).setCellValue(String.valueOf(LocalDate.now()));
            sheet.getRow(4).getCell(5).setCellValue(businessReportDataVO.getTodayNewMember());
            sheet.getRow(4).getCell(7).setCellValue(businessReportDataVO.getTotalMember());
            sheet.getRow(5).getCell(5).setCellValue(businessReportDataVO.getTotalMember());
            sheet.getRow(5).getCell(7).setCellValue(businessReportDataVO.getThisMonthNewMember());
            sheet.getRow(5).getCell(7).setCellValue(businessReportDataVO.getThisMonthNewMember());
            sheet.getRow(7).getCell(7).setCellValue(businessReportDataVO.getTodayVisitsNumber());
            sheet.getRow(8).getCell(5).setCellValue(businessReportDataVO.getThisWeekOrderNumber());
            sheet.getRow(8).getCell(7).setCellValue(businessReportDataVO.getThisWeekVisitsNumber());
            sheet.getRow(9).getCell(5).setCellValue(businessReportDataVO.getThisMonthOrderNumber());
            sheet.getRow(9).getCell(7).setCellValue(businessReportDataVO.getThisMonthVisitsNumber());
            for (int i = 0; i < 4; i++) {
                HotSetmealVO hotSetmealVO = hotSetmeal.get(i);

                sheet.getRow(12 + i).getCell(4).setCellValue(hotSetmealVO.getName());
                sheet.getRow(12 + i).getCell(5).setCellValue(hotSetmealVO.getSetmeal_count());
                sheet.getRow(12 + i).getCell(6).setCellValue(hotSetmealVO.getProportion());
                sheet.getRow(12 + i).getCell(7).setCellValue("");

            }

            //用过输出流将Excel文件下载到客户端浏览器
            ServletOutputStream outputStream = response.getOutputStream();
            excel.write(outputStream);

            //关闭资源
            excel.close();
            outputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}
